package com.beijiteshop.shop.ui.shopcar

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Toast
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.beijiteshop.libcommon.ext.databinding.bindView
import com.beijiteshop.libcommon.pagestate.LoadSirHelper
import com.beijiteshop.libcommon.utils.DensityUtil
import com.beijiteshop.libcommon.utils.EventUtil
import com.beijiteshop.shop.R
import com.beijiteshop.shop.app.PageIndex
import com.beijiteshop.shop.base.BaseContainerFragment
import com.beijiteshop.shop.databinding.FragmentShopCarBinding
import com.beijiteshop.shop.model.api.response.ProductBean
import com.beijiteshop.shop.model.api.response.ShoppingCartBean
import com.beijiteshop.shop.model.entity.ShopCarProductEntity
import com.beijiteshop.shop.model.event.EventKey
import com.beijiteshop.shop.ui.detail.ProductDetailFragment
import com.beijiteshop.shop.ui.order.fragment.OrderConfirmListFragment
import com.beijiteshop.shop.ui.shopcar.adapter.ShopCarAdapter
import com.beijiteshop.shop.ui.shopcar.vm.ShopCarVM
import com.blankj.utilcode.util.LogUtils
import com.kingja.loadsir.core.LoadService
import com.yanzhenjie.recyclerview.SwipeMenuItem
import com.yanzhenjie.recyclerview.widget.DefaultItemDecoration
import kotlinx.coroutines.delay
import org.koin.android.scope.lifecycleScope
import org.koin.android.viewmodel.ext.android.viewModel

/**
 * 购物车首页
 */
class ShopCarFragment : BaseContainerFragment(R.layout.fragment_shop_car),View.OnClickListener {

    companion object {

        private const val INIT_PAGE = 1

        @JvmStatic
        fun newInstance() =
            ShopCarFragment()
    }

    private val mBinding: FragmentShopCarBinding by bindView()
    private val mShopCarVM: ShopCarVM by viewModel()
    private val mShopCarAdapter: ShopCarAdapter = ShopCarAdapter(mutableListOf())
    private var mPage: Int = 1
    private lateinit var mLoadSir: LoadService<Any>

    override fun initView(view: View) {
        mLoadSir = LoadSirHelper.register(mBinding.shopCarRv){
            initList()
        }

        setPaymentsGoodsNum(0)
        setTotalPrice(0f)
        initRecyclerView()
    }

    override fun initData() {

    }

    override fun initEvent() {
        startObserve()

        EventUtil.observe<Any>(this,EventKey.REFRESH_SHOP_CART){
            initList()
        }
        mBinding.shopCarSelectAllIv.setOnClickListener(this)
        mBinding.shopCarSettlementBtn.setOnClickListener(this)
    }

    override fun onLazyLoad() {
        initList()
    }

    private fun initRecyclerView(){
        mShopCarAdapter.apply {
            addFooterView(LayoutInflater.from(requireContext()).inflate(R.layout.footer_shop_car,null))
            setOnItemChildClickListener { _, view, position ->
                when(view.id){
                    R.id.shop_car_select_iv -> {
                        chooseItem(position)
                        updateSelectAllView()
                        updateSelectProductAction()
                    }
                    R.id.shop_car_reduce_tv -> {
                        changeCount(false,data[position].productBean.bus_ShopCartID,position)
                    }
                    R.id.shop_car_plus_tv -> {
                        changeCount(true,data[position].productBean.bus_ShopCartID,position)
                    }
                }
            }

            //ITEM点击事件
            setOnItemClickListener { _, _, position ->
                startProductDetailActivity(data[position].productBean)
            }
        }
        mBinding.shopCarRv.apply {
            addItemDecoration(DefaultItemDecoration(ContextCompat.getColor(requireContext(),R.color.colorLightBg),20,20))
            layoutManager = LinearLayoutManager(requireContext())
            itemAnimator = null//去掉动画效果
            setSwipeMenuCreator { leftMenu, rightMenu, position ->
                val menuItem = SwipeMenuItem(requireContext())
                menuItem.width = DensityUtil.dp2px(requireContext(),60)
                menuItem.height = ConstraintLayout.LayoutParams.MATCH_PARENT
                menuItem.text = resources.getString(R.string.delete)
                menuItem.setTextColor(ContextCompat.getColor(requireContext(),R.color.colorWhite))
                menuItem.textSize = 16
                menuItem.setBackground(R.color.color_primary)
                rightMenu.addMenuItem(menuItem)
            }
            setOnItemMenuClickListener { menuBridge, adapterPosition ->
                menuBridge.closeMenu()
                deleteGoods(mShopCarAdapter.data[adapterPosition].productBean.bus_ShopCartID)

            }
            adapter = mShopCarAdapter
        }
    }

    /**
     * 设置去结算的商品数量
     */
    private fun setPaymentsGoodsNum(num: Int){
        val result = String.format(resources.getString(R.string.settlement),num)
        mBinding.shopCarSettlementBtn.text = result
    }

    /**
     * 设置选中的商品总价
     */
    private fun setTotalPrice(price: Float){
        mBinding.shopCarTotalPriceTv.text = price.toString()
    }

    /**
     * 选中或取消选中item
     */
    private fun chooseItem(position: Int){
        if (position < mShopCarAdapter.data.size){
            val check = mShopCarAdapter.data[position].isSelect
            mShopCarAdapter.data[position].isSelect = !check
            mShopCarAdapter.notifyItemChanged(position)
        }
    }

    /**
     * 更新全选按钮状态
     */
    private fun updateSelectAllView(){
        if (mShopCarAdapter.data.isNullOrEmpty()){
            mBinding.shopCarSelectAllIv.isSelected = false
        }else{
            val data = mShopCarAdapter.data.filter { !it.isSelect }
            mBinding.shopCarSelectAllIv.isSelected = data.isNullOrEmpty()
        }
    }

    /**
     * 选中或取消选中商品后的操作
     */
    private fun updateSelectProductAction(){
        val data = mShopCarAdapter.data.filter { it.isSelect }
        updateTotalPrice(data)
        updateSettleGoodsNum(data)
    }

    /**
     * 更新共计价格
     */
    private fun updateTotalPrice(data: List<ShopCarProductEntity>){
        var totalPrice: Float = 0f
        data.forEach {
            if (it.isSelect){
                totalPrice += (it.productBean.sellingPrice.toFloat() * it.num.get())
            }
        }
        mBinding.shopCarTotalPriceTv.text = String.format("%.2f",totalPrice)
    }

    /**
     * 更新要结算的商品数量
     */
    private fun updateSettleGoodsNum(data: List<ShopCarProductEntity>){
        var size = 0
        data.forEach {
            if (it.isSelect){
                size += it.num.get()
            }
        }
        mBinding.shopCarSettlementBtn.text = String.format(resources.getString(R.string.settlement,size))
    }

    /**
     * 全选或取消全选
     */
    private fun chooseAllProducts(isSelectAll: Boolean){
        mShopCarAdapter.apply {
            data.forEach {
                it.isSelect = isSelectAll
            }
            notifyDataSetChanged()
        }
    }

    /**
     * 更新某个商品的数量
     */
    private fun updateProductNum(position: Int,plus: Boolean){
        if (mShopCarAdapter.data.size > position){
            var itemNum = mShopCarAdapter.data[position].num.get()
            if (itemNum >= 1){
                if (plus){
                    itemNum++
                }else{
                    if (itemNum > 1){
                        itemNum--
                    }else{
                        Toast.makeText(requireContext(),
                            resources.getString(R.string.select_at_least_one_item),
                            Toast.LENGTH_SHORT)
                            .show()
                    }
                }
            }
            mShopCarAdapter.apply {
                data[position].num.set(itemNum)
                data[position].isSelect = true
                notifyItemChanged(position)
            }
            updateSelectAllView()
            updateSelectProductAction()
        }
    }

    override fun onClick(v: View) {
        when(v.id){
            R.id.shop_car_select_all_iv -> {
                if (mShopCarAdapter.data.size > 0){
                    v.isSelected = !v.isSelected
                    chooseAllProducts(v.isSelected)
                    updateSelectProductAction()
                }
            }
            R.id.shop_car_settlement_btn -> {
                val products = mShopCarAdapter.data.filter { it.isSelect }
                if (products.isNotEmpty()){
                    val cartIds = arrayOfNulls<String>(products.size)
                    products.forEachIndexed { index, shopCarProductEntity ->
                        cartIds[index] = shopCarProductEntity.productBean.bus_ShopCartID
                    }
                    startActivity(PageIndex.CART_ORDER_INFO,Bundle().apply {
                        putStringArray(OrderConfirmListFragment.CART_IDS,cartIds)
                    })
                }
            }
        }
    }

    private fun initList(){
        mPage = INIT_PAGE
        showLoadingPage()
        mShopCarVM.getShopCarList(mPage)
    }

    /**
     * 更新列表加载状态
     */
    private fun updateRVState(error: Boolean,data: MutableList<ShopCarProductEntity>?){
        if (error){
            if (mShopCarAdapter.loadMoreModule.isLoading){
                mShopCarAdapter.loadMoreModule.loadMoreFail()
            }
        }else{
            if (mShopCarAdapter.loadMoreModule.isLoading){
                if (data.isNullOrEmpty()){
                    mShopCarAdapter.loadMoreModule.loadMoreEnd()
                }else{
                    mShopCarAdapter.addData(data)
                    mShopCarAdapter.loadMoreModule.loadMoreComplete()
                }
            }
        }
    }

    private fun startObserve(){
        mShopCarVM.apply {
            liveShopCarList.observeKt {data ->
                if (mPage == INIT_PAGE){
                    showSuccess()
                    setPaymentsGoodsNum(0)
                    setTotalPrice(0f)
                    mShopCarAdapter.setNewInstance(data)
                }else{
                    updateRVState(false,data)
                }
            }

            liveEmpty.observeKt {
                if (mPage == INIT_PAGE){
                    setPaymentsGoodsNum(0)
                    setTotalPrice(0f)
                    mShopCarAdapter.data.clear()
                    mShopCarAdapter.notifyDataSetChanged()
                    showEmpty()
                }else{
                    updateRVState(false,null)
                }
            }

            liveError.observeKt {
                if (mPage == INIT_PAGE){
                    showError()
                }else{
                    updateRVState(true,null)
                }
            }

            liveNetError.observeKt {
                if (mPage == INIT_PAGE){
                    showNetError()
                }else{
                    updateRVState(true,null)
                }
            }

            //删除商品
            liveDeleteGoods.observeKt {result ->
                hideLoading()
                result?.let {
                    val(success,msg) = it
                    if (success){
                        val id = msg
                        var itemIndex = -1
                        mShopCarAdapter.apply {
                            data.forEachIndexed { index, shopCarProductEntity ->
                                if (shopCarProductEntity.productBean.bus_ShopCartID == id){
                                    itemIndex = index
                                    return@forEachIndexed
                                }
                            }
                            if (itemIndex >=0 ){
                                removeAt(itemIndex)
                                notifyItemRemoved(itemIndex)
                            }
                            LogUtils.dTag("TAG","data size:${data.size}")
                            updateSelectAllView()
                            updateTotalPrice(data)
                            updateSettleGoodsNum(data)

                            if (data.size == 0){
                                showEmpty()
                            }
                        }
                    }else{
                        msg?.let {
                            showToastInCenter(msg)
                        }
                    }
                }
            }

            //修改商品数量成功
            liveChangeCount.observeKt {
                hideLoading()
                it?.let {result ->
                    val(add,position) = result
                    updateProductNum(position,add)
                }
            }

            //修改商品数量失败
            liveChangeCountFailed.observeKt {
                hideLoading()
                showToastInCenter(it?:resources.getString(R.string.operation_failed))
            }
        }
    }

    /**
     * 删除商品
     */
    private fun deleteGoods(id: String){
        showLoading()
        mShopCarVM.deleteGoods(id)
    }

    /**
     * 修改购物车商品数量
     */
    private fun changeCount(add: Boolean,id: String,position: Int){
        if (add){
            showLoading()
            mShopCarVM.addCount(id,position)
        }else{
            if (mShopCarAdapter.data[position].num.get()- 1 <= 0){
                showToastInCenter(resources.getString(R.string.select_at_least_one_item))
            }else{
                showLoading()
                mShopCarVM.reduceCount(id,position)
            }
        }
    }

    private fun startProductDetailActivity(cartBean: ShoppingCartBean){
        val productBean = ProductBean(cartBean.bus_GoodsID,cartBean.goodName,"","",
            cartBean.isSellout,cartBean.marketPrice,cartBean.path,cartBean.sellingPrice,
            null,cartBean.color,cartBean.specification)
        startActivity(PageIndex.PRODUCT_DETAIL, Bundle().apply {
            putParcelable(ProductDetailFragment.BUNDLE_PRODUCT,productBean)
        })
    }

    private fun showLoadingPage(){
        LoadSirHelper.showLoading(mLoadSir)
    }

    private fun showError(){
        LoadSirHelper.showError(mLoadSir)
    }

    private fun showEmpty(){
        LoadSirHelper.showEmpty(mLoadSir)
    }

    private fun showNetError(){
        LoadSirHelper.showNetError(mLoadSir)
    }

    private fun showSuccess(){
        LoadSirHelper.showSuccess(mLoadSir)
    }
}